<template>
	<view class="">
		<u-input
			:type="disabled ? '' : 'select'"
			:disabled="disabled"
			inputAlign="right"
			@click="onTextClick"
			:selectOpen="showPicker"
			:value="showText"
			:customStyle="{ color: disabled ? '#909399' : '#303133' }"
		></u-input>
		<u-popup
			v-model="showPicker"
			mode="bottom"
			:popup="false"
			:mask="true"
			:closeable="true"
			:safe-area-inset-bottom="true"
			close-icon-color="#ffffff"
			:z-index="uZIndex"
			:maskCloseAble="maskCloseAble"
			@close="close"
		>
			<u-tabs v-if="showPicker" :list="genTabsList" :is-scroll="true" :current="tabsIndex" @change="tabsChange" ref="tabs"></u-tabs>
			<view class="area-box">
				<view class="u-flex" :class="{ change: isChange }">
					<view class="area-item">
						<view class="u-padding-10 u-bg-gray" style="height: 100%;">
							<scroll-view :scroll-y="true" style="height: 100%">
								<u-cell-group>
									<u-cell-item v-for="(item, index) in provinces" :title="item.label" :arrow="false" :index="index" :key="index" @click="provinceChange($event, true)">
										<u-icon v-if="isChooseP && province === index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
									</u-cell-item>
								</u-cell-group>
							</scroll-view>
						</view>
					</view>
					<view class="area-item">
						<view class="u-padding-10 u-bg-gray" style="height: 100%;">
							<scroll-view :scroll-y="true" style="height: 100%">
								<u-cell-group v-if="isChooseP">
									<u-cell-item v-for="(item, index) in citys" :title="item.label" :arrow="false" :index="index" :key="index" @click="cityChange($event, true)">
										<u-icon v-if="isChooseC && city === index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
									</u-cell-item>
								</u-cell-group>
							</scroll-view>
						</view>
					</view>

					<view class="area-item">
						<view class="u-padding-10 u-bg-gray" style="height: 100%;">
							<scroll-view :scroll-y="true" style="height: 100%">
								<u-cell-group v-if="isChooseC">
									<u-cell-item v-for="(item, index) in areas" :title="item.label" :arrow="false" :index="index" :key="index" @click="areaChange">
										<u-icon v-if="isChooseA && area === index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
									</u-cell-item>
								</u-cell-group>
							</scroll-view>
						</view>
					</view>
				</view>
			</view>
		</u-popup>
	</view>
</template>

<script>
/**
 * city-select 省市区级联选择器
 * @property {String Number} z-index 弹出时的z-index值（默认1075）
 * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker（默认true）
 * @property {String} default-region 默认选中的地区，中文形式
 * @property {String} default-code 默认选中的地区，编号形式
 */
export default {
	name: 'city-select',
	props: {
		// 通过双向绑定控制组件的弹出与收起
		value: {
			type: Array,
			default() {
				return [];
			}
		},
		// 默认显示的地区，可传类似["河北省", "秦皇岛市", "北戴河区"]
		defaultRegion: {
			type: Array,
			default() {
				return [];
			}
		},
		placeholder: {
			type: String,
			default: '请选择'
		},
		// 是否允许通过点击遮罩关闭Picker
		maskCloseAble: {
			type: Boolean,
			default: true
		},
		// 弹出的z-index值
		zIndex: {
			type: [String, Number],
			default: 0
		},
		disabled: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			showPicker: false,
			cityValue: '',
			isChooseP: false, //是否已经选择了省
			province: -1, //省级下标
			provinces: [],
			isChooseC: false, //是否已经选择了市
			city: -1, //市级下标
			citys: [],
			isChooseA: false, //是否已经选择了区
			area: -1, //区级下标
			areas: [],
			tabsIndex: 0,

			selectedArea: [],
			selectedAreaCode: []
		};
	},
	created() {
		this.getProvinceData().then(res => {
			this.provinces = res;
			setTimeout(() => {
				this.init();
			}, 200);
		});
	},

	computed: {
		isChange() {
			return this.tabsIndex > 1;
		},
		genTabsList() {
			let tabsList = [
				{
					name: '请选择'
				}
			];
			if (this.isChooseP) {
				tabsList[0]['name'] = this.provinces[this.province]['label'];
				tabsList[1] = {
					name: '请选择'
				};
			}
			if (this.isChooseC) {
				tabsList[1]['name'] = this.citys[this.city]['label'];
				tabsList[2] = {
					name: '请选择'
				};
			}
			if (this.isChooseA) {
				tabsList[2]['name'] = this.areas[this.area]['label'];
			}
			return tabsList;
		},
		uZIndex() {
			// 如果用户有传递z-index值，优先使用
			return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
		},
		showText() {
			if (this.selectedArea.length > 0) {
				if (!this.selectedArea[0]) {
					return this.placeholder;
				} else {
					return this.selectedArea.filter(item => item).join('-');
				}
			} else {
				return this.placeholder;
			}
		}
	},

	methods: {
		onTextClick() {
			if (this.disabled) {
				return false;
			}
			this.showPicker = true;
		},
		init() {
			if (this.value.length == 3) {
				this.setProvince('', this.value[0]);
				this.getCityData(this.value[0]).then(res => {
					this.citys = res;
					this.setCity('', this.value[1]);
					this.getAreaData(this.value[1]).then(res => {
						this.areas = res;
						this.setArea('', this.value[2]);
					});
				});
			} else if (this.defaultRegion.length == 3) {
				this.setProvince(this.defaultRegion[0], '');
				this.setCity(this.defaultRegion[1], '');
				this.setArea(this.defaultRegion[2], '');
			}
		},
		setProvince(label = '', value = '') {
			this.provinces.map((v, k) => {
				if (value ? v.value == value : v.label == label) {
					this.provinceChange(k);
				}
			});
		},
		setCity(label = '', value = '') {
			this.citys.map((v, k) => {
				if (value ? v.value == value : v.label == label) {
					this.cityChange(k);
				}
			});
		},
		setArea(label = '', value = '') {
			this.areas.map((v, k) => {
				if (value ? v.value == value : v.label == label) {
					this.areaChange(k);
				}
			});
		},
		close() {
			this.selectedArea = [];
			this.selectedAreaCode = [];
			this.showPicker = false;

			let province, city, area;
			if (this.province >= 0) {
				province = this.provinces[this.province];
			}
			if (this.city >= 0) {
				city = this.citys[this.city];
			}
			if (this.area >= 0) {
				area = this.areas[this.area];
			}
			let provinceCode = '',
				cityCode = '',
				areaCode = '';
			let provinceName = '',
				cityName = '',
				areaName = '';
			if (province && province.value) {
				provinceCode = province.value;
				provinceName = province.label;
			}
			if (city && city.value) {
				cityCode = city.value;
				cityName = city.label;
			}
			if (area && area.value) {
				areaCode = area.value;
				areaName = area.label;
			}
			this.selectedArea = [provinceName, cityName, areaName];
			this.selectedAreaCode = [provinceCode, cityCode, areaCode];
			this.$emit('input', this.selectedAreaCode);

			let result = {};
			result.province = province;
			result.city = city;
			result.area = area;
			this.$emit('city-change', result);
		},
		tabsChange(index) {
			this.tabsIndex = index;
		},
		provinceChange(index, reload) {
			this.isChooseP = true;
			this.isChooseC = false;
			this.isChooseA = false;
			this.province = index;
			this.tabsIndex = 1;
			this.city = -1;
			this.area = -1;
			this.selectedArea[0] = this.provinces[index].label;

			if (reload) {
				this.getCityData(this.provinces[index].value).then(res => {
					this.citys = res;
				});
			}
		},
		cityChange(index, reload) {
			this.isChooseC = true;
			this.isChooseA = false;
			this.city = index;
			this.tabsIndex = 2;
			this.area = -1;
			this.selectedArea[1] = this.citys[index].label;

			if (reload) {
				this.getAreaData(this.citys[index].value).then(res => {
					this.areas = res;
				});
			}
		},
		areaChange(index) {
			this.isChooseA = true;
			this.area = index;
			let result = {};
			result.province = this.provinces[this.province];
			result.city = this.citys[this.city];
			result.area = this.areas[this.area];
			this.selectedArea[2] = result.area.label;
			this.$emit('city-change', result);
			this.close();
		},

		getProvinceData() {
			return new Promise((resolve, reject) => {
				this.$u.api
					.getAreaList({
						AreaId: 0,
						Level: 2
					})
					.then(res => {
						const { ResultCode, AreaList } = res;
						if (ResultCode === 1) {
							const areaData = AreaList.map(item => {
								return {
									value: item.Key,
									label: item.Value
								};
							});
							resolve(areaData);
						}
					});
			});
		},

		getCityData(provinceId) {
			return new Promise((resolve, reject) => {
				this.$u.api
					.getAreaList({
						AreaId: provinceId,
						Level: 3
					})
					.then(res => {
						const { ResultCode, AreaList } = res;
						if (ResultCode === 1) {
							const areaData = AreaList.map(item => {
								return {
									value: item.Key,
									label: item.Value
								};
							});
							resolve(areaData);
						}
					});
			});
		},

		getAreaData(cityId) {
			return new Promise((resolve, reject) => {
				this.$u.api
					.getAreaList({
						AreaId: cityId,
						Level: 4
					})
					.then(res => {
						const { ResultCode, AreaList } = res;
						if (ResultCode === 1) {
							const areaData = AreaList.map(item => {
								return {
									value: item.Key,
									label: item.Value
								};
							});
							resolve(areaData);
						}
					});
			});
		}
	}
};
</script>
<style lang="scss">
.area-box {
	width: 100%;
	overflow: hidden;
	height: 800rpx;

	> view {
		width: 150%;
		transition: transform 0.3s ease-in-out 0s;
		transform: translateX(0);

		&.change {
			transform: translateX(-33.3333333%);
		}
	}

	.area-item {
		width: 33.3333333%;
		height: 800rpx;
	}
}
</style>
